package cn.jbolt.core.db.sql;

import cn.jbolt.core.base.config.JBoltConfig;
import cn.jbolt.core.kit.JBoltSaasTenantKit;
import cn.jbolt.core.model.base.JBoltModelConfig;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Model;

public class SqlUtil {
	private static final String TRUE_CHAR = "'1'";
	private static final String FALSE_CHAR = "'0'";
	private static final String TRUE = "1";
	private static final String FALSE = "0";

	private static final String TABLENAME_ENDLINE = "_";

	/**
	 * 处理表名
	 * @param modelClass
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public static String processTenantTableName(Class<? extends Model> modelClass) {
		String tableName = JBoltModelConfig.me.getTableName(modelClass);
		if(!JBoltConfig.SAAS_ENABLE || !JBoltModelConfig.me.isSeparate(modelClass) || !JBoltSaasTenantKit.me.isOk()) {
			return tableName;
		}
		String tenantId = JBoltSaasTenantKit.me.getIdToStr();
		if(StrKit.isBlank(tenantId)) {
			throw new RuntimeException("租户ID不能为空");
		}
		String end = TABLENAME_ENDLINE + tenantId;
		if(tableName.endsWith(end)) {
			return tableName;
		}
		return tableName + end;
	}

	public static String processTenantTableName(String tableName) {
		if(!JBoltConfig.SAAS_ENABLE || !JBoltSaasTenantKit.me.isOk()) {
			return tableName;
		}
		String tenantId = JBoltSaasTenantKit.me.getIdToStr();
		if(StrKit.isBlank(tenantId)) {
			throw new RuntimeException("租户ID不能为空");
		}
		String end = TABLENAME_ENDLINE+tenantId;
		if(tableName.endsWith(end)) {
			return tableName;
		}
		return tableName+end;
	}

	@SuppressWarnings("rawtypes")
	public static String processTenantTableNameInSql(Class<? extends Model> modelClass,String sql) {
		if(!JBoltConfig.SAAS_ENABLE || !JBoltModelConfig.me.isSeparate(modelClass) || !JBoltSaasTenantKit.me.isOk()) {
			return sql;
		}
		String tenantId = JBoltSaasTenantKit.me.getIdToStr();
		if(StrKit.isBlank(tenantId)) {
			throw new RuntimeException("租户ID不能为空");
		}
		String end = TABLENAME_ENDLINE+tenantId;
		String tableName = JBoltModelConfig.me.getTableName(modelClass);
		String newTableName = tableName + end;
		if(sql.indexOf(tableName)!=-1 && sql.indexOf(newTableName)==-1) {
			return sql.replace(tableName, newTableName);
		}
		return sql;
	}

	public static Object processBooleanValue(Object value) {
		if (value instanceof Boolean) {
			return boolToInt(value.toString().trim());
		}
		return value;
	}

	public static String boolToChar(boolean value) {
		return value ? TRUE_CHAR : FALSE_CHAR;
	}

	public static String boolToChar(String value) {
		return Boolean.parseBoolean(value.toString().trim()) ? TRUE_CHAR : FALSE_CHAR;
	}

	public static String boolToInt(boolean value) {
		return value ? TRUE : FALSE;
	}

	public static String boolToInt(String value) {
		return Boolean.parseBoolean(value.toString()) ? TRUE : FALSE;
	}

	/**
	 * 处理sql表达式里的值 处理boolean null 处理sql注入问题
	 *
	 * @param value
	 * @return
	 */
	public static String sqlValue(Object value) {
		if (value == null) {
			return "NULL";
		}
		String sqlValue = value.toString().trim();
		if (StrKit.isBlank(sqlValue)) {
			return "NULL";
		}
		if (value instanceof Number || value instanceof SqlExpress) {
			return sqlValue;
		}
		if (value instanceof Boolean) {
			if (sqlValue.equalsIgnoreCase("true")) {
				return TRUE_CHAR;
			}
			return FALSE_CHAR;
		}

		if (value instanceof String) {
			String tempValue = sqlValue.toLowerCase();
			if ("like".equals(tempValue) || tempValue.startsWith("like ") || tempValue.indexOf(" like ") != -1
					|| (sqlValue.toLowerCase().indexOf("to_date(") != -1
							&& sqlValue.toLowerCase().indexOf("yyyy-mm-dd hh24:mi:ss") != -1)) {
				return sqlValue;
			}

			if (sqlValue.indexOf("'") != -1) {
				sqlValue = sqlValue.replace("'", "''");
			}

			// 如果是特殊is not判断 直接输出
			if (sqlValue.indexOf("is ") != -1 || sqlValue.indexOf(" not ") != -1 || sqlValue.indexOf(" in(") != -1
					|| sqlValue.indexOf(" in (") != -1) {
				return sqlValue;
			}

		}
		return "'" + sqlValue + "'";
	}

	/**
	 * 处理like 的值
	 *
	 * @param value
	 * @return
	 */
	public static String likeValue(Object value) {
		if (value == null) {
			return "";
		}
		String sqlValue = value.toString().trim();
		if (StrKit.isBlank(sqlValue)) {
			return "";
		}
		if (sqlValue.indexOf("'") != -1) {
			sqlValue = sqlValue.replace("'", "''");
		}
		return sqlValue;
	}

	/**
	 * 处理数据库函数 findInset
	 *
	 * @param dbType
	 * @param values
	 * @param value
	 * @param valuesIsTableColumn
	 * @return
	 */
	public static Object[] findInSet(String dbType, Object values, Object value, boolean valuesIsTableColumn) {
		String key = "";
		Object v = "";
		switch (dbType) {
		case DBType.MYSQL:
			key = " find_in_set('" + value + "'," + values + ") >";
			v = 0;
			break;
		case DBType.ORACLE:
			key = " (',' || " + (valuesIsTableColumn ? values : "'" + values + "'") + " ||',')";
			v = "like '%," + value + ",%'";
			break;
		case DBType.POSTGRESQL:
			key = " (',' || " + (valuesIsTableColumn ? values : "'" + values + "'") + " ||',')";
			v = "like '%," + value + ",%'";
			break;
		case DBType.SQLSERVER:
			key = " (',' + " + values + " + ',')";
			v = "like '%," + value + ",%'";
			break;
		case DBType.DM:
			key = " (',' + " + values + " + ',')";
			v = "like '%," + value + ",%'";
			break;
		}
		return new Object[] { key, v };
	}
}
